package com.baymax.test.scene.demo

import android.app.Instrumentation
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.os.Message
import android.os.Messenger
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.core.view.setPadding
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.baymax.test.scene.BaseScene
import com.baymax.test.scene.addButton
import com.baymax.test.scene.newFlexContainer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * client 会发送的message:
 * message{what=0} :注册，保留replyTo
 * message{what=-1} :反注册，删除replyTo
 * message{what=1} :查询是否显示， 回复client -> message { what =1 , data=bundle{show:true/false}}
 * message{what=2 ，data=bundle{keycode:[19,20,4...],isFocus:true}} :需要server端上焦 ,keycode为触发的按键 ，回复client->message { what =2 , data=bundle{show:true/false}}
 *
 * server 需要发送的信息message:
 *
 * message{what=3,data=bundle{keycode:[19,20,4...],isFocus:false}}:server失去焦点并且client需要处理的按键
 * message{what=-2 } :server端主动断开或者出现异常断开通知
 */
class VRFocusScene : BaseScene() {
    var job: Job = Job()
    override fun onCreateView(p0: LayoutInflater, p1: ViewGroup, p2: Bundle?): View {
        return p1.newFlexContainer(attachParent = false) {
            this.setPadding(30)

            var mService: Messenger? = null
            var isShow = false
            var currentFocus: View? = null
            val clientMessager = Messenger(Handler(Looper.getMainLooper()) { m ->
                println("client <-- : $m")
                val bundle = (m.peekData() ?: m.obj as? Bundle) ?: bundleOf()
                val keys = bundle.keySet()
                println("client <-- : ${keys.map { it to bundle.get(it) }.joinToString()}")
                Toast.makeText(
                    requireActivity(),
                    keys.map { it to bundle.get(it) }.joinToString(),
                    Toast.LENGTH_SHORT
                ).show()
                when (m.what) {
                    -2 -> {
                        Toast.makeText(requireActivity(), "服务解绑成功！", Toast.LENGTH_SHORT)
                            .show()
                        mService = null
                    }

                    2 -> {
                        isShow = bundle.getBoolean("show")
                        if (isShow) {
                            currentFocus?.let {
                                p1.requestFocus()
                            }
                        }
                    }

                    3 -> {
                        if (isShow) {

                            val keycode = bundle.getInt("keycode")
                            currentFocus?.requestFocus()
                            if (keycode != KeyEvent.KEYCODE_DPAD_LEFT) {
                                launch(Dispatchers.Default) {
                                    job.cancel()
                                    delay(100)
                                    Instrumentation().sendKeySync(
                                        KeyEvent(
                                            0,
                                            bundle.getInt("keycode")
                                        )
                                    )
                                }

                            }
                        }

                    }

                    else -> {}
                }
                true
            })

            fun sendMessage(what: Int, bundleOf: Bundle = bundleOf()) {
                val msg: Message = Message.obtain(null, what, 0, 0)
                msg.replyTo = clientMessager
                msg.obj = bundleOf
                msg.data = bundleOf
                kotlin.runCatching {
                    mService?.send(msg)
                }
            }


            val conn = object : ServiceConnection {

                override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                    println("onServiceConnected <-- : $name")
                    mService = Messenger(service)
                    Toast.makeText(requireActivity(), "服务绑定成功:${name}", Toast.LENGTH_SHORT)
                        .show()

                }

                override fun onServiceDisconnected(name: ComponentName?) {
                    mService = null
                }
            }
            lifecycle.addObserver(object : DefaultLifecycleObserver {
                override fun onDestroy(owner: LifecycleOwner) {
                    super.onDestroy(owner)
                    requireActivity().unbindService(conn)
                }
            })
            addButton("start service") {
                requireActivity().bindService(Intent().apply {
                    component = ComponentName(
                        "com.hc.jsyd.vr",
                        "com.hc.baihejingling.service.MessengerService"
                    )

                }, conn, Context.BIND_AUTO_CREATE)
            }

            addButton("register") {
                sendMessage(0)
            }
            addButton("unregister") {
                sendMessage(-1)
            }

            addButton("requset alive") {
                sendMessage(1)
            }

            addButton("requset focus -> left") {
                sendMessage(2, bundleOf("keycode" to 21, "isFocus" to true))
            }

            val r = addButton("requset focus -> right") {
                sendMessage(2, bundleOf("keycode" to 22, "isFocus" to true))
                currentFocus = findFocus()
            }
            r.id = View.generateViewId()
            r.setOnFocusChangeListener { v, hasFocus ->
                v.background =
                    if (hasFocus) ColorDrawable(Color.YELLOW) else ColorDrawable(Color.DKGRAY)
            }
            addButton("requset focus -> up") {
                sendMessage(2, bundleOf("keycode" to 19, "isFocus" to true))
            }
            addButton("requset focus -> down") {
                sendMessage(2, bundleOf("keycode" to 20, "isFocus" to true))
            }

            addButton("按键获取焦点") {
                val btn = this
                startView(true)
                job.cancel()
                job = launch {
                    var down = 3
                    while (down >= 0) {
                        btn.text = "${down}秒后失去焦点"
                        delay(1000)
                        down--
                        btn.text = "按键获取焦点"
                    }
                    startView(false)
                }
                job.invokeOnCompletion { this.text = "按键获取焦点" }
            }

            addButton("show view") {
                startView(false)
            }

        }
    }


    fun startView(requestFocus: Boolean) {
        Intent().apply {
            component = ComponentName(
                "com.hc.jsyd.vr",
                "com.hc.baihejingling.service.SuspendWindowService"
            )
            putExtra("IS_FOCUS", requestFocus)
            putExtra("ACTION_DATA", "{\"anim_suspend_type\":2}")
        }.apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                requireActivity().startForegroundService(this)
            } else {
                requireActivity().startService(this)
            }
        }

//        val parent = FrameLayout(requireActivity())
//        val lp = WindowManager.LayoutParams()
//        lp.format = PixelFormat.TRANSPARENT;
//        lp.gravity = Gravity.BOTTOM or Gravity.END
//        lp.x = 100
//        lp.y = 100
//        lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
//        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
//        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//        lp.type = LAST_SUB_WINDOW - 1
//
//        button = parent.addButton("hello") {
//            Toast.makeText(requireActivity().applicationContext, "this is click", Toast.LENGTH_LONG)
//                .show()
//        }
//
//        try {
//
//            requireActivity().windowManager.addView(parent, lp)
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }

    }


}
